package start.spring.basic.util.common;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.NoSuchAlgorithmException;

import com.alibaba.fastjson.JSONObject;

import start.spring.basic.constant.ProConstant;

/**
 *
 * ****************************************************************************
 * 用户请求token的相关操作
 *
 * @author(作者)：xuyongyun	
 * @author(复审人)：	Administrator 2016-9-6
 * @version(版本)1.0
 * @since 1.0
 ******************************************************************************
 */
public class JwtTokenUtil {
	
	private final static String ALG_NAME = EncryptUtil.SHA_256;
	
	private final static String SPLIT = "~";
	
	private final static String web_address = "";
	
	private final static long login_exprie_time = 3600;
	
	private final static String jwt_key = "S89aSs8Hl3d071qo1";
	
	/**
	 * 生成JwtToken
	 *	
	 * @param userId 用户唯一标识，默认为用户名
	 * @param ip 用户登录请求的ip
	 * @return
	 * @throws Exception 
	 * @since           1.0
	 */
	public static String genToken(String userId) throws Exception{
		String jwtToken = null;
		try{
			String header = genHeader();
			String payload = genPayload(userId);
			String signature = genSignature(header,payload);
			jwtToken = header + SPLIT + payload + SPLIT + signature;
		}catch(Exception e){
			throw e;
		}
		return jwtToken;
	}
	
	/**
	 * 从token还原用户信息
	 *	
	 * @param jwtToken
	 * @return
	 * @since           1.0
	 */
	public static String getUserInfo(String jwtToken) {
		String yhid = null;
		try {
			jwtToken = URLDecoder.decode(jwtToken,"utf-8");
			String[] jwtTokenParts = jwtToken.split(SPLIT);
			String payload = jwtTokenParts[1];
			payload = URLDecoder.decode(payload,"utf-8");
			JSONObject requestInfoJson = JSONObject.parseObject(payload);
			yhid = requestInfoJson.getString("yhid");
		} catch (UnsupportedEncodingException e) {
			
		}
		return yhid;
		
	}

	/**
	 * 生成jwttoken的header
	 *	
	 * @return
	 * @throws Exception 
	 * @since           1.0
	 */
	private static String genHeader() throws Exception {
		
		String header = "";
		
		JSONObject headerJson = new JSONObject();
		headerJson.put("type", "JWT");
		headerJson.put("alg", ALG_NAME);
		
		header = EncryptUtil.encryptBASE64(headerJson.toString().getBytes());
		
		return header;
	}

	/**
	 * 生成jwttoken的Payload
	 *	
	 * @param userId 用户的唯一公开标识
	 * @return
	 * @throws Exception 
	 * @since           1.0
	 */
	private static String genPayload(String userId) throws Exception {
		String payload = null;
		//token生成时间
		String iat = String.valueOf(System.currentTimeMillis());
		
		//用户唯一标识
		String yhid = userId;
		//签发token网站
		String iss = web_address;
		if(ProConstant.PRAMS.containsKey("web_address")) {
			iss = ProConstant.PRAMS.getString("web_address");
		}
		
		//Token有效时间
		long exprieTime = login_exprie_time;
		if(ProConstant.PRAMS.containsKey("ProConstant.PRAMS")) {
			exprieTime = ProConstant.PRAMS.getLongValue("login_exprie_time");
		}
		String exp = String.valueOf(System.currentTimeMillis() + 1000*exprieTime);
		
		
		JSONObject requestInfoJson = new JSONObject();
		requestInfoJson.put("yhid", yhid);
		requestInfoJson.put("iss", iss);
		requestInfoJson.put("iat", iat);
		requestInfoJson.put("exp", exp);
		requestInfoJson.put("fwcs", "0");
		
		payload = URLEncoder.encode(requestInfoJson.toString(),"utf-8");
		
		return payload;
	}
	
	/**
	 * 生成token签名
	 *	
	 * @param header
	 * @param payload
	 * @return
	 * @throws NoSuchAlgorithmException 
	 * @since           1.0
	 */
	private static String genSignature(String header, String payload) throws NoSuchAlgorithmException {
		String signature = null;
		String secret = jwt_key;
		//数据库配置了密钥，则覆盖默认密钥
		if(ProConstant.PRAMS.containsKey("jwt_key")) {
			secret = ProConstant.PRAMS.getString("jwt_key");
		}	
		String source = header + payload + secret;
		signature = EncryptUtil.encrypt(source, ALG_NAME);
		return signature;
	}
	
	/**
	 * 验证token是否有效
	 * 
	 * @param token 待验证token
	 * @return true有效，false无效
	 * @since           1.0
	 */
	public static boolean validateToken(String token){
		boolean isValidate = false;
		try{
			if(token!=null&&token.length()>0){
				String[] jwtTokenParts = token.split(SPLIT);
				//校验签名
				if(jwtTokenParts[2].equals(
						genSignature(jwtTokenParts[0], jwtTokenParts[1]))){
					isValidate = true;
				}else{
					isValidate = false;
				}
			}
		}catch(Exception e){
			isValidate = false;
		}
		return isValidate;
	}
	
	/**
	 * 根据已验证的有效token，生成新的token用于下次请求
	 * 
	 * @param token
	 * @return
	 * @since           1.0
	 */
	public static String genReqToken(String token) {
		
		try{
			String[] tokens = token.split(SPLIT);
			String header = tokens[0];
			String payload = tokens[1];
			
			payload = URLDecoder.decode(payload,"utf-8");
			JSONObject obj = JSONObject.parseObject(payload);

			String yhid = obj.getString("yhid");
			String iss = obj.getString("iss");
			String iat = obj.getString("iat");
			String exp = obj.getString("exp");
			String fwcs = obj.getString("fwcs");
			
			//更新访问次数
			fwcs = String.valueOf(Integer.parseInt(fwcs)+1);
			
			JSONObject requestInfoJson = new JSONObject();
			requestInfoJson.put("yhid", yhid);
			requestInfoJson.put("iss", iss);
			requestInfoJson.put("iat", iat);
			requestInfoJson.put("exp", exp);
			requestInfoJson.put("fwcs", fwcs);
			
			payload = URLEncoder.encode(requestInfoJson.toString(),"utf-8");
			
			String signature = genSignature(header,payload);
			
			token = header + SPLIT + payload + SPLIT + signature;
		}catch(Exception e){
			e.printStackTrace();
			token = null;
		}
		return token;
	}
	

}
